package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> clazz = null;
		
		clazz = Class.forName("reflection.Person");
		
		//获取所有属性
		Field[] fields = clazz.getDeclaredFields();
		//获取所有方法包括私有方法，不包括父类继承来的
		Method[] methods = clazz.getDeclaredMethods();
		//获取方法包括父类继承来的，不包括私有方法
		Method[] withoutPrivateMethods = clazz.getMethods();
		//获取所有构造函数
		Constructor[] constructors = clazz.getConstructors();
		
		//获得类私有方法
		Method eat = clazz.getDeclaredMethod("eat",String.class);
		
		Constructor constructor = clazz.getConstructor(String.class,int.class);
		//利用有参构造函数创建对象
		Object applePerson = constructor.newInstance("apple",18);
		eat.setAccessible(true);
		eat.invoke(applePerson, "apple");
		
		//利用默认构造函数创建对象
		Object person = clazz.newInstance();
		//设置true才能调用私有方法，私有属性也是如此
		eat.setAccessible(true);
		eat.invoke(person,"banana");
		
		System.out.println("****************new start**********************");
		/**
		 * Bootstrap Classloader 引导类加载器
		 *           ↑ 
		 * Extension Classloader 扩展类加载器
		 * 			 ↑
		 * Application ClassLoader 应用程序类加载器
		 */
		
		//获取一个系统类加载器，当前这个类就是由他加载
		ClassLoader classLoader = ClassLoader.getSystemClassLoader();
		System.out.println(classLoader);
		
		//获取系统类加载器的父类加载器（扩展类加载器，可以获取）
		classLoader = classLoader.getParent();
		System.out.println(classLoader);
		
		//获取扩展类加载器的父类加载器（引导类加载器，不可获取）  
		classLoader = classLoader.getParent();
		System.out.println(classLoader);
		
		//测试 JDK 提供的 Object 类由哪个类加载器负责加载（引导类）
		Class clazz2 = Class.forName("java.lang.Object").getClass();	
		System.out.println(clazz2.getClassLoader());
		System.out.println("fuck");
	}
	
}
